﻿using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace SharpSoft.Web
{
    /// <summary>
    /// 页面静态化服务
    /// </summary>
    public class StaticizeService
    {
        /// <summary>
        /// 储存静态化页面的根路径
        /// </summary>
        public const string Staticize_StorePath = "StaticizePages";
        IWebHostEnvironment env;
        Dictionary<string, bool> updateInfo = new Dictionary<string, bool>();
        public StaticizeService(IWebHostEnvironment p_env)
        {
            env = p_env;
        }
        /// <summary>
        /// 获取储存静态化文件的绝对路径
        /// </summary>
        /// <returns></returns>
        private string GetRootPath()
        {
            return System.IO.Path.Combine(this.env.ContentRootPath, Staticize_StorePath);
        }


        private static object asyncState = new object();
        /// <summary>
        /// 通知指定路由的页面已变化，下次读取时需要先缓存。（再确认页面内容改变时调用，例如对信息页面进行提交后。）
        /// </summary>
        /// <param name="route"></param>
        public void NotifyUpdate(string[] route)
        {
            var key = StaticizeHelper.GetRouteKey(route);
            lock (asyncState)
            {
                if (updateInfo.ContainsKey(key))
                {
                    updateInfo[key] = true;
                }
                else
                {
                    updateInfo.Add(key, true);
                }
            }
        }
        /// <summary>
        /// 通知指定路由的页面已缓存
        /// </summary>
        /// <param name="route"></param>
        private void NotifyCached(string[] route)
        {
            var key = StaticizeHelper.GetRouteKey(route);
            lock (asyncState)
            {
                if (updateInfo.ContainsKey(key))
                {
                    updateInfo.Remove(key);
                }
            }
        }
        /// <summary>
        /// 获取指定的页面是否需要缓存
        /// </summary>
        /// <param name="route"></param>
        /// <returns>true:需要缓存；false:不需要缓存</returns>
        public bool GetNeedCache(string[] route)
        {
            var key = StaticizeHelper.GetRouteKey(route);
            lock (asyncState)
            {
                if (updateInfo.ContainsKey(key) && updateInfo[key])
                {//为true则决定要更新缓存
                    return true;
                }
                else
                {//否则由缓存文件是否存在来决定是否要立即进行缓存
                    return !StaticizeHelper.ExistsStaticizeFile(GetRootPath(), route);
                }
            }
        }
        /// <summary>
        /// 立即缓存页面内容
        /// </summary>
        /// <param name="route"></param>
        /// <param name="content"></param>
        public void CachePage(string[] route, string content)
        {
            StaticizeHelper.WriteStaticizeFile(GetRootPath(), route, content);
            NotifyCached(route);
        }
        /// <summary>
        /// 删除页面的缓存文件
        /// </summary>
        /// <param name="route"></param>
        public void DeleteCachedPage(string[] route)
        {
            StaticizeHelper.DeleteStaticizeFile(GetRootPath(), route);
        }
        /// <summary>
        /// 删除全部的缓存文件（这可能是一个耗时操作）
        /// </summary>
        public void DeleteAllCached()
        {
            var folder = GetRootPath();
            //直接删除缓存目录
            if (System.IO.Directory.Exists(folder))
            {
                System.IO.Directory.Delete(folder, true);
            }
        }
        /// <summary>
        /// 获取缓存页面的内容
        /// </summary>
        /// <param name="route"></param>
        /// <returns></returns>
        public string GetCachedPageContent(string[] route)
        {
            return StaticizeHelper.ReadStaticizeFile(GetRootPath(), route);
        }
        /// <summary>
        /// 获取视图的渲染结果
        /// </summary>
        /// <param name="controller"></param>
        /// <param name="viewName"></param>
        /// <param name="model"></param>
        /// <param name="isPartialView"></param>
        /// <returns></returns>
        public async Task<string> GetViewRenderResult(Controller controller, string viewName, object model, bool isPartialView = false)
        {
            return await StaticizeHelper.GetViewRenderResult(controller, viewName, model, isPartialView);
        }
    }
}
